import requests
import logging
from typing import Dict, Any, Optional

logger = logging.getLogger(__name__)


class CoordinateService:
    """
    坐标获取服务 - 通用的地址转坐标服务
    """
    
    def __init__(self, api_url: str, token: str = None):
        """
        初始化坐标服务
        
        Args:
            api_url: API地址
            token: 访问令牌
        """
        self.api_url = api_url.rstrip('/')
        self.token = token
        self.session = requests.Session()
        
        # 设置默认headers
        if token:
            self.session.headers.update({
                'Authorization': f'Bearer {token}',
                'Content-Type': 'application/json'
            })
    
    def get_coordinates_by_address(self, address: str) -> Dict[str, Any]:
        """
        根据地址获取坐标
        
        Args:
            address: 地址字符串
            
        Returns:
            包含坐标信息的字典
        """
        try:
            # 构建请求参数 - 适配百度地图API格式
            params = {
                'address': address,
                'output': 'json'
            }
            
            # 如果有token，添加到参数中
            if self.token:
                params['ak'] = self.token
            
            logger.info(f"正在获取地址坐标: {address}")
            
            response = self.session.get(
                f"{self.api_url}",
                params=params,
                timeout=30
            )
            
            response.raise_for_status()
            data = response.json()
            
            # 解析百度地图API响应
            if data.get('status') == 0 and data.get('result'):
                location = data['result']['location']
                return {
                    'success': True,
                    'lng': location['lng'],
                    'lat': location['lat'],
                    'address': address,
                    'formatted_address': data['result'].get('formatted_address', address)
                }
            else:
                error_msg = data.get('message', '地址解析失败')
                logger.warning(f"地址解析失败: {address}, 错误: {error_msg}")
                return {
                    'success': False,
                    'message': error_msg,
                    'address': address
                }
                
        except requests.exceptions.RequestException as e:
            logger.error(f"坐标API请求失败: {str(e)}")
            return {
                'success': False,
                'message': f"网络请求失败: {str(e)}",
                'address': address
            }
        except Exception as e:
            logger.error(f"坐标获取异常: {str(e)}")
            return {
                'success': False,
                'message': f"坐标获取异常: {str(e)}",
                'address': address
            }
    
    def batch_get_coordinates(self, addresses: list) -> Dict[str, Any]:
        """
        批量获取坐标
        
        Args:
            addresses: 地址列表
            
        Returns:
            批量坐标结果
        """
        results = []
        
        for address in addresses:
            if not address or not address.strip():
                results.append({
                    'success': False,
                    'message': '地址为空',
                    'address': address
                })
                continue
            
            result = self.get_coordinates_by_address(address.strip())
            results.append(result)
        
        success_count = sum(1 for r in results if r['success'])
        
        return {
            'success': success_count > 0,
            'total': len(addresses),
            'success_count': success_count,
            'results': results
        }
    
    def format_coordinates(self, lng: float, lat: float) -> str:
        """
        格式化坐标为字符串
        
        Args:
            lng: 经度
            lat: 纬度
            
        Returns:
            格式化的坐标字符串 "经度,纬度"
        """
        return f"{lng},{lat}"
    
    def parse_coordinates(self, coordinates_str: str) -> Optional[Dict[str, float]]:
        """
        解析坐标字符串
        
        Args:
            coordinates_str: 坐标字符串 "经度,纬度"
            
        Returns:
            包含经纬度的字典，解析失败返回None
        """
        try:
            if not coordinates_str:
                return None
                
            parts = coordinates_str.split(',')
            if len(parts) != 2:
                return None
                
            lng = float(parts[0].strip())
            lat = float(parts[1].strip())
            
            return {'lng': lng, 'lat': lat}
        except (ValueError, IndexError):
            logger.warning(f"坐标字符串解析失败: {coordinates_str}")
            return None